package com.baoxian.workschedule.util

import com.baoxian.workschedule.model.BaseTimeModel
import com.baoxian.workschedule.model.CommonDayTimeModel
import com.baoxian.workschedule.model.WeekWorkDayModel
import org.apache.commons.lang.StringUtils

import java.text.DateFormat
import java.text.SimpleDateFormat
import java.util.regex.Matcher
import java.util.regex.Pattern

/**
 * User: ZhengCongChun
 * Date: 13-7-18
 * Time: 下午4:02
 * @Version 1.0
 *      To change this template use File | Settings | File Templates.
 */
class CommonUtil {
    /**
     * 获得日期是星期几
     * @param dateStr:日期：格式：yyyy-MM-dd
     * @return
     * @throws Throwable
     */
    public static Object dayForWeek(String dateStr) throws Throwable {
        if (StringUtils.isBlank(dateStr) || dateStr.length() < 10) {
            throw IllegalArgumentException("==== 不是正确是日期时间参数 ====")
        }

        if (!matcherDateFormat(dateStr, ConstantsUtil.DATE_FORMAT) && dateStr.length() > 10) {
            dateStr = dateStr.substring(0, 10)
        }
        def date = new Date().parse('yyyy-MM-dd', dateStr?.toString()?.trim())
        return date?.getDay().intValue() == 0 ? 7 : date?.getDay().intValue()
    }

    /**
     * 比较两个日期(格式：yyyy-MM-dd HH:mm:ss)的大小
     * @param originalDate     比较的日期
     * @param comparedDate     被比较的日期
     * @return  1：大于，-1：小于： 0：相等
     */
    public static int compareToDate(String originalDate, String comparedDate, String dateFormatStr = ConstantsUtil.DATE_TIME_FULL_FORMAT) {
        if (StringUtils.isBlank(originalDate) || StringUtils.isBlank(comparedDate)) {
            throw IllegalArgumentException("==== 对比的两日期不能为空 ====")
        }

        DateFormat dateFormat = new SimpleDateFormat(dateFormatStr)

        try {
            Date orDate = dateFormat.parse(originalDate)
            Date coDate = dateFormat.parse(comparedDate)

            if (orDate.getTime() > coDate.getTime()) {
                //originalDate > comparedDate
                return 1
            } else if (orDate.getTime() < coDate.getTime()) {
                //originalDate < comparedDate
                return -1
            } else {
                //originalDate == comparedDate
                return 0
            }
        } catch (Exception e) {
            e.printStackTrace()
        }

        return 0
    }

    /**
     * 计算两个日期时间之间的时间差(秒)
     * @param currentDateTime   yyyy-MM-dd HH:mm:ss
     * @param orgCloseDateTime  yyyy-MM-dd HH:mm:ss
     * @return  时间差
     */
    public static int calcTimeLengthOfTwoDate(String currentDateTime, String orgCloseDateTime) {
        if (StringUtils.isBlank(currentDateTime) || StringUtils.isBlank(orgCloseDateTime)) {
            throw IllegalArgumentException("==== 参数不能为空 ====")
        }

        SimpleDateFormat sdf = new SimpleDateFormat(ConstantsUtil.DATE_TIME_FULL_FORMAT)

        Calendar currentCalendar = Calendar.getInstance()
        Calendar closeCalendar = Calendar.getInstance()
        def currentTime = sdf.parse(currentDateTime?.trim())
        def closeTime = sdf.parse(orgCloseDateTime?.trim())
        currentCalendar.set(currentTime.getYear(), currentTime.getMonth(), currentTime.getDate(), currentTime.getHours(), currentTime.getMinutes(), currentTime.getSeconds())
        closeCalendar.set(closeTime.getYear(), closeTime.getMonth(), closeTime.getDate(), closeTime.getHours(),closeTime.getMinutes(), closeTime.getSeconds())

        //通过两日历的毫秒来求差
        def timeLength = Math.round((closeCalendar.getTimeInMillis() - currentCalendar.getTimeInMillis())/1000)

        return timeLength
    }

    /**
     * 判断日期字符串是否符合长日期字符串格式(yyyy-MM-dd HH:mm:ss)
     * @param datetime
     * @return
     */
    public static boolean matcherDateFormat(String datetime, String format) {
        if (StringUtils.isBlank(datetime) || StringUtils.isBlank(format)) {
            throw IllegalArgumentException("==== 参数不能为空 ====")
        }

        //yyyy-MM-dd HH:mm:ss
        String el

        if (format == ConstantsUtil.DATE_TIME_FULL_FORMAT) {
            el = /^\d{4}-\d{2}-\d{2}\s\d{2}:\d{2}:\d{2}$/
        }
        if (format == ConstantsUtil.TIME_FORMAT){
            el = /^\d{2}:\d{2}:\d{2}$/
        }

        if (format == ConstantsUtil.DATE_FORMAT) {
            el = /^\d{4}-\d{2}-\d{2}$/
        }


        Pattern pattern = Pattern.compile(el)
        Matcher matcher = pattern.matcher(datetime)

        return matcher.matches()
    }

    /**
     * 是否是休息日
     * @param executeDate
     * @param holidays
     * @return
     */
    static CommonDayTimeModel isWorkingDate(String executeDate, List<CommonDayTimeModel> dateTimeList) {
        CommonDayTimeModel result

        if (!CommonUtil.matcherDateFormat(executeDate, ConstantsUtil.DATE_FORMAT)) {
            executeDate = executeDate.substring(0, 10)
        }

        //判断是否在机构具体休息日范围内
        dateTimeList.each {
            int start = CommonUtil.compareToDate(it?.startDate, executeDate, ConstantsUtil.DATE_FORMAT)
            int end = CommonUtil.compareToDate(executeDate, it?.endDate, ConstantsUtil.DATE_FORMAT)
            if ((start == -1 || start == 0) && (end == -1 || end == 0)) {
                result = it
                return
            }
        }

        //判断是否在全局默认休息日范围内
        return result
    }

    /**
     * 是否在星期工作日
     * @param weekDay
     * @param weekWorkDay
     * @return
     */
    static WeekWorkDayModel isWeekDay(int weekDay, List<WeekWorkDayModel> weekWorkDay) {
        WeekWorkDayModel result
        weekWorkDay?.each {
            if (it.startDay <= weekDay && it.endDay >= weekDay) {
                println(it)
                result = it
                return
            }
        }

        return result
    }

    /**********************************以下代码均为20130902重构**************************************/
    /**
     * 处理任务的日期是否是特定工作日
     * @param specialDayList
     *      特定工作日集合
     * @param processDate
     *      处理任务的日期
     * @return
     */
    static boolean isSpeicalWorkDay(List<CommonDayTimeModel> specialDayList, String processDate) {
        boolean result

        if (!matcherDateFormat(processDate, ConstantsUtil.DATE_FORMAT)) {
            processDate = processDate.substring(0, 10)
        }

        //判断是否特定工作日
        specialDayList.each {
            int start = compareToDate(it?.startDate, processDate, ConstantsUtil.DATE_FORMAT)
            int end = compareToDate(processDate, it?.endDate, ConstantsUtil.DATE_FORMAT)
            if ((start == -1 || start == 0) && (end == -1 || end == 0)) {
                result = true
                return
            }
        }

        return result
    }

    /**
     * 是否为特定的星期工作日
     * @param weekDayList
     *      特定星期工作日期集合
     * @param processDate
     *      处理任务的日期
     * @return
     */
    static boolean isSpecialWeekWorkDay(List<WeekWorkDayModel> weekDayList, String processDate) {
        boolean result

        int weekDay = dayForWeek(processDate)

        weekDayList?.each {
            if (it.startDay <= weekDay && it.endDay >= weekDay) {
                result = true
                return
            }
        }

        return result
    }

    /**
     *处理任务的日期是否在特定休息日中
     * @param specialHolidayList
     * @param processDate
     * @return
     */
    static boolean isSpecialRestHoliday(List<CommonDayTimeModel> specialHolidayList, String processDate) {
        return isSpeicalWorkDay(specialHolidayList, processDate)
    }

    /**
     * 处理任务的日期是否在全局节假日中
     * @param holiday
     * @param processDate
     * @return
     */
    static boolean isGlobalRestHoliday(List<CommonDayTimeModel> holiday, String processDate) {
        isSpeicalWorkDay(holiday, processDate)
    }

    /**
     * 获得处理任务当日上下班时间
     * @return
     */
    static Map getCurrentWorkingHours(String processDate, BaseTimeModel workTime) {
        Map result = [:]
        if (!matcherDateFormat(processDate, ConstantsUtil.DATE_FORMAT)) {
            processDate = processDate.substring(0, 10)
        }
        String beginWorkingTime = "${processDate} " + "${workTime?.startTime}"
        String closeWorkingTime = "${processDate} " + "${workTime?.endTime}"
        result.put(ConstantsUtil.WORK_BEGIN_TIME, "${beginWorkingTime}")
        result.put(ConstantsUtil.WORK_CLOSE_TIME, "${closeWorkingTime}")

        return result
    }

    static boolean isProcessTimeOut(Map scheduleDateTime, int preProcessTime, String processDate) {
        boolean result

        //计算机构处理任务的时间与机构运营下班时间的时间差：是否大于 preProcessTime
        if (scheduleDateTime) {
            //当前执行任务的时间距离机构营业下班时间的时长(秒)
            int timeLen
            String orgBeginTime = scheduleDateTime?.get(ConstantsUtil.WORK_BEGIN_TIME)
            String orgCloseTime = scheduleDateTime?.get(ConstantsUtil.WORK_CLOSE_TIME)

            int start = compareToDate(orgBeginTime, processDate)
            int end = compareToDate(processDate, orgCloseTime)
            //判断处理时间是否在机构运行时间内
            if ((start == -1 || start == 0) && (end == -1 || end == 0)) {
                timeLen = calcTimeLengthOfTwoDate(processDate, orgCloseTime)
                result = timeLen < preProcessTime
            } else {
                result = true
            }
        }

        return result
    }
}
